﻿#include "BaseTypes.h"

Mat::~Mat() {
	// release();
}

Mat::Mat(int y, int x) {
	rows = y;
	cols = x;
	data = new double* [y];
	for (int i = 0; i < y; i++) {
		data[i] = new double[x];
	}
}
Mat::Mat(int y, int x, double val) {
	rows = y;
	cols = x;
	data = new double* [y];
	for (int i = 0; i < y; i++) {
		data[i] = new double[x];
		for (int j = 0; j < x; j++) {
			data[i][j] = val;
		}
	}
}
double& Mat::at(int y, int x) const {
	return data[y][x];
}
void Mat::release() const {
	for (int i = 0; i < rows; i++) {
		delete[] data[i];
	}
	delete[] data;
}
Mat Mat::operator()(int y_begin, int y_end, int x_begin, int x_end) {
	Mat new_mat(y_end - y_begin, x_end - x_begin);
	for (int i = y_begin; i < y_end; i++) {
		for (int j = x_begin; j < x_end; j++) {
			new_mat.at(i - y_begin, j - x_begin) = (double)at(i, j);
		}
	}
	return new_mat;
}
Mat Mat::clone() {
	return operator()(0, rows, 0, cols);
}
void Mat::blur(double sigma) {
	if (sigma <= 0)return;
	// 计算高斯核
	int radius = static_cast<int>(std::ceil(2.0f * sigma));
	int kernelSize = 2 * radius + 1;
	std::vector<double> weights(kernelSize);

	double sum = 0.0f;

	for (int i = -radius; i <= radius; ++i) {
		double x = i;
		weights[i + radius] = exp(-x * x / (2 * sigma * sigma));
		sum += weights[i + radius];
	}

	// 归一化
	for (int i = 0; i < kernelSize; ++i) {
		weights[i] /= sum;
	}

	for (int i = 0; i < rows; i++) {
		double val = 0;
		for (int j = -radius; j < radius; j++) {
			if (i + j >= rows || i + j < 0) {
				break;
			}
			val += weights[j + radius] * data[i + j][0];
		}
		at(i, 0) = val;
	}
	weights.clear();
}

Mat vconcat(Mat& a, Mat& b) {
	Mat new_mat(a.rows + b.rows, a.cols);
	for (int i = 0; i < a.rows; i++) {
		memcpy(new_mat.data[i], a.data[i], a.cols * sizeof(double));
	}
	for (int i = 0; i < b.rows; i++) {
		memcpy(new_mat.data[i + a.rows], b.data[i], a.cols * sizeof(double));
	}
	return new_mat;
}